package uvt.map.controll;

import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import org.openstreetmap.gui.jmapviewer.Coordinate;

import uvt.gui.mainframe.CreateTransportationNetworkPanel;
import uvt.gui.mainframe.MainFrame;
import uvt.map.JMapViewer;
import uvt.map.PositionsSettings;


public class MyMapController extends JMapController 
                             implements MouseListener, MouseMotionListener,
                                        MouseWheelListener {

    private static final int MOUSE_BUTTONS_MASK = MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK
                                                  | MouseEvent.BUTTON2_DOWN_MASK;
    private static final int MAC_MOUSE_BUTTON3_MASK = MouseEvent.CTRL_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK;
    private Point lastDragPoint;
    private boolean isMoving = false;
    private boolean movementEnabled = true;
    private int movementMouseButton = MouseEvent.BUTTON1;
    private int movementMouseButtonMask = MouseEvent.BUTTON1_DOWN_MASK;
    private boolean wheelZoomEnabled = true;
    private boolean doubleClickZoomEnabled = true;
    private PositionsSettings posSettings;
    
    public MyMapController(JMapViewer map) {
    	super(map);
        posSettings = PositionsSettings.getInstance();
    }

	public void mouseDragged(MouseEvent e) {
        if(!movementEnabled || !isMoving)
            return;
        if((e.getModifiersEx() & MOUSE_BUTTONS_MASK) == movementMouseButtonMask || 
             isPlatformOsx() && e.getModifiersEx() == MAC_MOUSE_BUTTON3_MASK) {
        	Point p = e.getPoint();
            if(lastDragPoint != null) {
                int diffx = lastDragPoint.x - p.x;
                int diffy = lastDragPoint.y - p.y;
                map.moveMap(diffx, diffy);
            }
            lastDragPoint = p;
       }
    }

    public void mouseClicked(MouseEvent e) {
    	if(e.getButton() == MouseEvent.BUTTON1) {
    		Point p = e.getPoint();
    		switch(e.getClickCount()) {
        	case 1:
        		if(MainFrame.getChkSetPositions().isSelected()) {
        			Coordinate coord = map.getPosition(p);
            		if(MainFrame.getChkAddMapElements().isSelected()) {
            			posSettings.coordinateSettngsBehaviourSSSPanel(coord);
            		} else {
            			posSettings.coordinateSettingsBehaviourMapPanel(coord);
            		}
        		}
        		break;
        	case 2:
        		map.zoomIn(e.getPoint());
        		break;
        	}
    	}
    }

    public void mousePressed(MouseEvent e) {
        if(e.getButton() == movementMouseButton || isPlatformOsx() && e.getModifiersEx() == MAC_MOUSE_BUTTON3_MASK) {
        	lastDragPoint = null;
            isMoving = true;
        }
    }

    public void mouseReleased(MouseEvent e) {
        if(e.getButton() == movementMouseButton || isPlatformOsx() && e.getButton() == MouseEvent.BUTTON1) {
            lastDragPoint = null;
            isMoving = false;
        }
    }

    public void mouseWheelMoved(MouseWheelEvent e) {
        if(wheelZoomEnabled) {
            map.setZoom(map.getZoom() - e.getWheelRotation(), e.getPoint());
        }
    }

    public boolean isMovementEnabled() {
        return movementEnabled;
    }

    public void setMovementEnabled(boolean movementEnabled) {
        this.movementEnabled = movementEnabled;
    }

    public int getMovementMouseButton() {
        return movementMouseButton;
    }

    public void setMovementMouseButton(int movementMouseButton) {
    	this.movementMouseButton = movementMouseButton;
        switch (movementMouseButton) {
            case MouseEvent.BUTTON1:
                movementMouseButtonMask = MouseEvent.BUTTON1_DOWN_MASK;
                break;
            case MouseEvent.BUTTON2:
                movementMouseButtonMask = MouseEvent.BUTTON2_DOWN_MASK;
                break;
            case MouseEvent.BUTTON3:
                movementMouseButtonMask = MouseEvent.BUTTON3_DOWN_MASK;
                break;
            default:
                throw new RuntimeException("Unsupported button");
        }
    }

    public boolean isWheelZoomEnabled() {
        return wheelZoomEnabled;
    }

    public void setWheelZoomEnabled(boolean wheelZoomEnabled) {
        this.wheelZoomEnabled = wheelZoomEnabled;
    }

    public boolean isDoubleClickZoomEnabled() {
        return doubleClickZoomEnabled;
    }

    public void setDoubleClickZoomEnabled(boolean doubleClickZoomEnabled) {
        this.doubleClickZoomEnabled = doubleClickZoomEnabled;
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseMoved(MouseEvent e) {
        if(isPlatformOsx()) {
            if(!movementEnabled || !isMoving)
            	return;
            if(e.getModifiersEx() == MouseEvent.CTRL_DOWN_MASK) {
                Point p = e.getPoint();
                if(lastDragPoint != null) {
                    int diffx = lastDragPoint.x - p.x;
                    int diffy = lastDragPoint.y - p.y;
                    map.moveMap(diffx, diffy);
                }
                lastDragPoint = p;
            }

        }

    }
    
    public static boolean isPlatformOsx() {
        String os = System.getProperty("os.name");
        return os != null && os.toLowerCase().startsWith("mac os x");
    }
    
}